package main

import "fmt"

/*
  defer语句
  go语言中的defer语句会将其后面跟随的语句进行延迟处理，在defer归属的函数即将
  返回时，将延迟处理的语句按defer定义的逆序进行执行，也就是先被defer的语句最后
  执行，最后被defer的语句先执行
*/

func main() {
	fmt.Println("start")
	defer fmt.Println("111")
	fmt.Println("middle")
	defer fmt.Println("222")
	fmt.Println("end")
	//start middle end 222   111  先打印222 在打印 111

	fn1()                     //内部是   开始 结束  self do
	fmt.Println(fn2(), "fn2") // 0   先return  后执行defer函数
	fmt.Println(fn3(), "fn3") // 1

	fmt.Println(fn4(), "fn4") //5
}

func fn1() {
	fmt.Println("开始")
	defer func() {
		fmt.Println("selt do")
	}()
	fmt.Println("结束")
}

func fn2() int {
	var a int
	defer func() {
		a++
	}()
	return a
}

func fn3() (a int) {
	defer func() {
		a++
	}()
	return a
}

func fn4() (x int) {
	defer func(x int) {
		fmt.Println("x=", x) // x=0
		x++
	}(x) //defer注册要延迟执行的函数时该函数
	fmt.Println("a=", x) //a=0
	return 5
}
